package com.starlink.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.starlink.common.utils.AssertUtil;
import com.starlink.context.SessionContext;
import com.starlink.model.dtomapper.SearchRecordDtoMapper;
import com.starlink.model.domain.SearchRecordDO;
import com.starlink.mapper.SearchRecordMapper;
import com.starlink.model.request.SearchRecordRequest;
import com.starlink.model.request.mall.MallSearchRequest;
import com.starlink.model.util.SearchRecordConvert;
import com.starlink.model.vo.MallPeripherySpecificationVO;
import com.starlink.model.vo.mall.MallSearchVO;
import com.starlink.service.MallPeripherySpecificationService;
import com.starlink.service.SearchRecordService;
import com.starlink.model.vo.SearchRecordVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhanghong
 */
@Service
public class SearchRecordServiceImpl extends ServiceImpl<SearchRecordMapper, SearchRecordDO> implements SearchRecordService {
    @Autowired
    private SearchRecordMapper searchRecordMapper;
    @Autowired
    private MallPeripherySpecificationService peripherySpecificationService;

    private static final int SIZE = 20;

    @Override
    public SearchRecordVO getByKey(long id) {
        SearchRecordVO searchRecordVO = SearchRecordDtoMapper.INSTANCE.do2VO(getById(id));
        return searchRecordVO;
    }

    @Override
    public List<SearchRecordVO> listQuery(SearchRecordRequest request) {
        List<SearchRecordDO> list = searchRecordMapper.selectDOList(SearchRecordDtoMapper.INSTANCE.request2DO(request));
        List<SearchRecordVO> searchRecordVOS = SearchRecordConvert.buildSearchRecordVoList(list);
        return searchRecordVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(SearchRecordRequest request) {
        save(SearchRecordDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(SearchRecordRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        saveOrUpdate(SearchRecordDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByIds(String ids) {
        searchRecordMapper.deleteDOByIds(Convert.toStrArray(ids));
        return true;
    }

    @Override
    public PageInfo<List<MallSearchVO>> search(MallSearchRequest request, Pageable pageable) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<MallSearchVO> mallSearchVOS = searchRecordMapper.search(request);
        List<MallSearchVO> peripherys = mallSearchVOS.stream().filter(item -> item.getCategory() == 2).collect(Collectors.toList());
        PageHelper.clearPage();
        peripherys.forEach(item->{
            Long itemId = item.getId();
            MallPeripherySpecificationVO specificationVO = peripherySpecificationService.selectFirstByPeripheryId(itemId);
            if (specificationVO!=null){
                item.setPrice(specificationVO.getPrice());
                item.setVipPrice(specificationVO.getVipPrice());
                item.setSpecification(specificationVO.getSpecification());
                item.setSpecificationId(specificationVO.getId());
            }
        });
        return new PageInfo(mallSearchVOS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean searchSave(SearchRecordRequest request) {
        String record = request.getRecord();
        if (StringUtils.isNotEmpty(record)) {
            SearchRecordDO request2DO = SearchRecordDtoMapper.INSTANCE.request2DO(request);
            request2DO.setCreateTime(new Date());
            List<SearchRecordDO> searchRecordDOS = searchRecordMapper.selectByUserId(request.getUserId());
            if (CollectionUtils.isNotEmpty(searchRecordDOS)) {
                int size = searchRecordDOS.size();
                if (SIZE == size) {
                    SearchRecordDO searchRecordDO = searchRecordDOS.stream().min(Comparator.comparing(SearchRecordDO::getCreateTime)).orElse(null);
                    searchRecordDO.setRecord(request.getRecord());
                    searchRecordDO.setCreateTime(new Date());
                    searchRecordMapper.updateDO(searchRecordDO);
                } else {
                    SearchRecordDO searchRecordDO = searchRecordDOS.stream().filter(itm -> itm.getRecord().equals(record)).findFirst().orElse(null);
                    if (searchRecordDO!=null){
                        searchRecordDO.setUpdateTime(new Date());
                        searchRecordMapper.updateDO(searchRecordDO);
                    }else {
                        searchRecordMapper.insertDO(request2DO);
                    }
                }
            } else {
                searchRecordMapper.insertDO(request2DO);
            }
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean searchDeleted(Long userId) {
        searchRecordMapper.deletedByUserId(userId);
        return true;
    }

    @Override
    public List<SearchRecordVO> searchSelect() {
        Long userId = SessionContext.getWechatUserId();
        List<SearchRecordDO> searchRecordDOS = searchRecordMapper.selectByUserId(userId);
        return SearchRecordConvert.buildSearchRecordVoList(searchRecordDOS);
    }
}
